package dk.cs.wolverine.client;

import java.util.ArrayList;
import java.util.HashMap;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.StackLayoutPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.visualization.client.AbstractDataTable;
import com.google.gwt.visualization.client.AbstractDataTable.ColumnType;
import com.google.gwt.visualization.client.DataTable;
import com.google.gwt.visualization.client.VisualizationUtils;
import com.google.gwt.visualization.client.visualizations.PieChart;
import com.google.gwt.visualization.client.visualizations.PieChart.Options;

import dk.cs.wolverine.client.TextList.ListType;
import dk.cs.wolverine.shared.Answer;
import dk.cs.wolverine.shared.Question;
import dk.cs.wolverine.shared.ResultSet;
import dk.cs.wolverine.shared.Section;
import dk.cs.wolverine.shared.SelectQuestion;
import dk.cs.wolverine.shared.TextQuestion;

/**
 * This is the implementation of the overview for all answers given to the
 * questionnaire
 * 
 * @author Siyalrach Anton Thomas
 */
public class Overview implements EntryPoint {

	private final QuestionnaireServiceAsync qService = GWT.create(QuestionnaireService.class);
	
	public ArrayList<Section> sections;

	@Override
	public void onModuleLoad() {
		Runnable onLoadCallback = new Runnable() {
			public void run() {
				getQService().getSections(
						new AsyncCallback<ArrayList<Section>>() {
							@Override
							public void onSuccess(ArrayList<Section> result) {
								buildStackLayoutPanel(result);
//								buildStackLayoutPanel(buildTestSection()); // testing
							}
							@Override
							public void onFailure(Throwable caught) {
								Window.alert("An Error have occurred while getting Sections");
							}
						});
			}
		};
		// Skal vente på at Googel Chart API er blevet loaded ind, før
		// begynder at bruge API'en
		VisualizationUtils.loadVisualizationApi(onLoadCallback,
				PieChart.PACKAGE);
	}

	private void buildStackLayoutPanel(ArrayList<Section> sections) {
		if (sections.size() <= 0) {
			// Vi har ingen sections i vores DB
			return;
		}

		StackLayoutPanel p = new StackLayoutPanel(Unit.EM);

		for (Section section : sections) {
			p.add(buildQuestions(section), new HTML(section.getName()), 3);
		}
		
		p.setHeight(600+"px");
		
		RootPanel.get("content").add(p);
	}

	private ScrollPanel buildQuestions(final Section section) {
		final VerticalPanel vp = new VerticalPanel();
		qService.getResultSets(new AsyncCallback<ArrayList<ResultSet>>() {
			@Override
			public void onFailure(Throwable caught) {
				vp.add(new HTML("PROBLEM GETTING RESULTSETS"));
			}

			@Override
			public void onSuccess(ArrayList<ResultSet> result) {
				ArrayList<Question> questionsAdded = new ArrayList<Question>();
				HashMap<Question, ArrayList<String>> textAnswers = new HashMap<Question, ArrayList<String>>();
				for(ResultSet set : result) {
					HashMap<Question, String> questions = set.getQuestionMap(section);
					for(Question q : questions.keySet()) {
						if(q.isTextQuestion()) {
							ArrayList<String> tmp = textAnswers.get(q);
							if(tmp == null) {
								tmp = new ArrayList<String>();
								textAnswers.put(q, tmp);
							}
							tmp.add(questions.get(q));
						}else{
							if(!questionsAdded.contains(q)) {
								vp.add(buildSelectQuestion(q.getSelectQuestion()));
								questionsAdded.add(q);
							}
						}
					}
				}
				for(Question q : textAnswers.keySet())
					vp.add(buildTextQuestion(q.getTextQuestion(), textAnswers.get(q)));
			}

		});
		return new ScrollPanel(vp);
	}

	/**
	 * Create a HtmlList, which only works for a TextQuestion
	 * 
	 * @param tq TextQuestion
	 * @param answers ArrayList<String>
	 * @return HtmlList widget
	 */
	private HtmlList buildTextQuestion(TextQuestion tq, ArrayList<String> answers) {
		HtmlList htmlList = new HtmlList(ListType.UNORDERED, tq.getQuestion());
		htmlList.addItems(answers);		
		return htmlList;
	}

	/**
	 * Create a PieChart, which only works for a SelectQuestion..
	 * 
	 * @param sq a SelectQuestion
	 * @return a DisclosurePanel which contains the Google Chart API PieChart image
	 */
	private DisclosurePanel buildSelectQuestion(SelectQuestion sq) {
		DisclosurePanel dp = new DisclosurePanel(sq.getQuestion());
		PieChart pie = new PieChart(createTable(sq.getAnswers()),
				createOptions(sq.getQuestion()));
		dp.add(pie);
		return dp;
	}

	/**
	 * Create a Option object used by the Google Chart API to set the property for the PieChart
	 * 
	 * @param question
	 * @return Options
	 */
	private Options createOptions(String question) {
		Options options = Options.create();
		options.setWidth(400);
		options.setHeight(240);
		options.set3D(true);
		options.setTitle(question);
		return options;
	}

	/**
	 * Create a datatable from our Answer list
	 * 
	 * @param answers
	 * @return {@link AbstractDataTable}
	 */
	private AbstractDataTable createTable(ArrayList<Answer> answers) {
		DataTable data = DataTable.create();
		data.addColumn(ColumnType.STRING, "Answer");
		data.addColumn(ColumnType.NUMBER, "Response");
		data.addRows(answers.size());
		for (int i = 0; i < answers.size(); i++) {
			data.setValue(i, 0, answers.get(i).getAnswer());
			data.setValue(i, 1, answers.get(i).getPoint());
		}
		return data;
	}

	
	private QuestionnaireServiceAsync getQService() {
		return qService;
	}

	@SuppressWarnings("unused")
	private ArrayList<Section> buildTestSection() {
		ArrayList<Section> sections = new ArrayList<Section>();

		//#### NEW SECTION ####//
		Section sec = new Section("Skole");

		SelectQuestion sq = new SelectQuestion("Er skolen kedeligt?", null, sec);
		ArrayList<Answer> answers = new ArrayList<Answer>();
		answers.add(new Answer("Ja", 2, sq)); answers.add(new Answer("Nej", 10, sq)); answers.add(new Answer("Ved ikke", 50, sq));
		sq.setAnswers(answers);
		Question q = new Question(sq);
		sec.addQuestion(q);

		sq = new SelectQuestion("Er du altid i skole?", null, sec);
		answers = new ArrayList<Answer>();
		answers.add(new Answer("Ja", 2, sq)); answers.add(new Answer("Nej", 50, sq)); answers.add(new Answer("Ikke altid", 20, sq));
		q = new Question(sq);
		sec.addQuestion(q);

		TextQuestion tq = new TextQuestion("Hvad vil du gøre bedre ved din Skole", sec);
		q = new Question(tq);
		sec.addQuestion(q);

		tq = new TextQuestion("Følger du med i undervisningstimerne", sec);
		q = new Question(tq);
		sec.addQuestion(q);

		sections.add(sec);

		//#### NEW SECTION ####//
		sec = new Section("Universitet");
		sq = new SelectQuestion("Hvad laver du på Universitet", null, sec);
		answers = new ArrayList<Answer>();
		answers.add(new Answer("Piller bussemænd", 40, sq)); answers.add(new Answer("Studere", 10, sq)); answers.add(new Answer("Ved ikke", 20, sq));
		q = new Question(sq);
		sec.addQuestion(q);

		sections.add(sec);

		return sections;
	}
}